package response

import (
	"engine/consts"
	"github.com/gin-gonic/gin"
	"go/types"
	"lib"
	sf_ctx "lib/sf-ctx"
	sferrors "lib/sf-errors"
	"net/http"
	"strconv"
	"strings"
)

type Response[T any] struct {
	Code        int    `json:"code"`
	Message     string `json:"message"`
	RealMessage string `json:"realMessage"`
	Data        T      `json:"data"`
}

type AuthResponse[T any, C any] struct {
	Token         string   `json:"token,omitempty" swaggertype:"string"`
	UserInfo      T        `json:"userInfo"`
	Company       C        `json:"company,omitempty"`
	Permissions   []string `json:"permissions"`
	WebsitePrefix string   `json:"websitePrefix"`
}

func Ok(c *gin.Context) {
	resp := Response[types.Nil]{
		Code:    int(sferrors.NoError),
		Message: sferrors.GetErrorResp(getLang(c), sferrors.NoError),
	}
	ctxValue, err := sf_ctx.GetCmsCtxValue(c)
	if err == nil {
		if ctxValue.User != nil {
			lib.UnRedisLock(strconv.Itoa(int(ctxValue.User.Id)))
		}
	}
	c.JSON(http.StatusOK, resp)
}

func OkData[T any](c *gin.Context, v T) {
	resp := Response[T]{
		Code:    int(sferrors.NoError),
		Message: sferrors.GetErrorResp(getLang(c), sferrors.NoError),
		Data:    v,
	}

	ctxValue, err := sf_ctx.GetCmsCtxValue(c)
	if err == nil {
		if ctxValue.User != nil {
			lib.UnRedisLock(strconv.Itoa(int(ctxValue.User.Id)))
		}
	}

	c.JSON(http.StatusOK, resp)
}

func getLang(ctx *gin.Context) string {
	local := strings.TrimSpace(ctx.GetHeader("Accept-Language"))
	if strings.EqualFold(local, "") {
		local = "zh-cn"
	} else {
		local = strings.ToLower(local)
	}
	return local
}

func Errors(c *gin.Context, err error) {
	resp := Response[types.Nil]{}
	newErr, ok := err.(*sferrors.Error)
	if ok {
		newErr = newErr.SetLang(c)
		actionType := sf_ctx.GetModule(c)
		resp.Code = 0
		resp.Message = newErr.GetMessage()
		resp.RealMessage = newErr.GetError()
		if resp.Message == "登录失败" {
			resp.Code = 401
		}
		if actionType == consts.ModuleAdmin {
			resp.Message += ": " + resp.RealMessage
		}
	} else {
		resp.Code = 0
		resp.Message = sferrors.New(err).SetCode(sferrors.SystemError).SetLang(c).Error()
	}

	c.JSON(200, resp)
}

func Error(c *gin.Context, err error) {
	resp := Response[types.Nil]{}
	newErr, ok := err.(*sferrors.Error)
	if ok {
		newErr = newErr.SetLang(c)
		//actionType := sf_ctx.GetModule(c)
		resp.Code = 0
		resp.Message = newErr.GetError()
		resp.RealMessage = newErr.GetError()
		if resp.Message == "登录失败" {
			resp.Code = 401
		}

		//if actionType == consts.ModuleAdmin {
		//	resp.Message += ": " + resp.RealMessage
		//}
	} else {
		resp.Code = 0
		resp.Message = sferrors.New(err).SetCode(sferrors.SystemError).SetLang(c).Error()
	}

	ctxValue, err := sf_ctx.GetCmsCtxValue(c)
	if err == nil {
		if ctxValue.User != nil {
			lib.UnRedisLock(strconv.Itoa(int(ctxValue.User.Id)))
		}
	}

	c.JSON(200, resp)
}

//func Error(c *gin.Context, errNo sferrors.ErrorCode) {
//	resp := Response[types.Nil]{
//		Code:    int(errNo),
//		Message: sferrors.GetErrorResp(c.GetHeader("lang"), errNo),
//	}
//	c.JSON(http.StatusOK, resp)
//}

//
//func RealError(c *gin.Context, errNo sferrors.ErrorCode, err error) {
//	resp := Response[types.Nil]{
//		Code:        int(errNo),
//		Message:     sferrors.GetErrorResp(c.GetHeader("lang"), errNo),
//		RealMessage: err.Error(),
//	}
//	c.JSON(http.StatusOK, resp)
//}
//
//func ErrorCode(c *gin.Context, httpCode int, errNo sferrors.ErrorCode) {
//	resp := Response[types.Nil]{
//		Code:    int(errNo),
//		Message: sferrors.GetErrorResp(c.GetHeader("lang"), errNo),
//	}
//	c.JSON(httpCode, resp)
//}
//
//func RealErrorCode(c *gin.Context, httpCode int, errNo sferrors.ErrorCode, err error) {
//	resp := Response[types.Nil]{
//		Code:        int(errNo),
//		Message:     sferrors.GetErrorResp(c.GetHeader("lang"), errNo),
//		RealMessage: err.Error(),
//	}
//	c.JSON(httpCode, resp)
//}
